﻿using System;
using System.Collections.Generic;
using System.Text;

using System.Runtime.InteropServices;

using SuperMapLib;
using SuperLayoutLib;

namespace JR_RouteAlarm
{
    class ZoneLayout : IWorkspace
    {
        /*定数*/
        private const int MAP_ON_LAYOUT_MARGIN_TOP = Utility.MAP_ON_LAYOUT_MARGIN_TOP;
        private const int MAP_ON_LAYOUT_MARGIN_LEFT = Utility.MAP_ON_LAYOUT_MARGIN_LEFT;

        /*変数*/
        private AxSuperMapLib.AxSuperWorkspace superWksp = null;
        private AxSuperLayoutLib.AxSuperLayout objLayout = null;
        private soLytMap objLytMap = null;
        private string[] routeNames = null;
        private string strMapName = String.Empty;

        public ZoneLayout(
            AxSuperMapLib.AxSuperWorkspace superWksp, AxSuperLayoutLib.AxSuperLayout objLayout)
        {
            this.superWksp = superWksp;
            this.objLayout = objLayout;
        }

        /// <summary>
        /// レイアウトを作成
        /// </summary>
        private void MakeLayout()
        {
            soLytElements objElements = null;
            soLytElement objElement = null;
            soLytPage objPage = null;

            objPage = objLayout.Page;
            SetupPage(objPage);

            objElements = objLayout.Elements;

            objElement = objElements.CreateElement(seLytObjType.sclytMap);
            objLytMap = objElement as soLytMap;
            AddMapToLayout(objPage);

            AddOthersToLayout(objElements);

            Marshal.ReleaseComObject(objElement);
            objElement = null;
            Marshal.ReleaseComObject(objElements);
            objElements = null;
        }

        /// <summary>
        /// レイアウト上にページサイズを設定
        /// </summary>
        /// <param name="objPage">設定先のページ</param>
        private void SetupPage(soLytPage objPage)
        {
            objPage.Size = seLytPrinterPaperSize.sclytDMPAPER_ISO_A1;
            objPage.Units = seLytPageUnits.scLytMillimeter;
        }

        /// <summary>
        /// レイアウトにマップを追加
        /// </summary>
        /// <param name="objPage">追加先のページ</param>
        private void AddMapToLayout(soLytPage objPage)
        {
            soRect objRect = null;

            objRect = objLytMap.Bounds;
            objRect.Top = MAP_ON_LAYOUT_MARGIN_TOP;
            objRect.Bottom = objPage.PageHeight - objLayout.PaperMarginBottom * 2;
            objRect.Left = MAP_ON_LAYOUT_MARGIN_LEFT;
            objRect.Right = objPage.PageWidth - objLayout.PaperMarginRight * 2;
            objLytMap.SetPosition(objRect);

            objLytMap.MapName = strMapName;
            objLytMap.MapScale = 1D / 20000;

            objRect = objLytMap.GeoBounds;
            objRect.Top = -11312;
            objRect.Bottom = -30224;
            objRect.Left = -20233;
            objRect.Right = -7360;
            objLytMap.GeoBounds = objRect;

            Marshal.ReleaseComObject(objRect);
            objRect = null;
            Marshal.ReleaseComObject(objPage);
            objPage = null;
        }

        /// <summary>
        /// レイアウトにマップに応じて、その他のコントロールを追加
        /// </summary>
        /// <param name="objElements">レイアウトの元素</param>
        private void AddOthersToLayout(soLytElements objElements)
        {
            double boundWidth = 0;
            SettingScale(objElements.CreateElement(seLytObjType.sclytScale), out boundWidth);
            SettingLog(objElements.CreateElement(seLytObjType.sclytPicture), boundWidth);
        }

        /// <summary>
        /// スケールを設定
        /// </summary>
        /// <param name="objElement">スケールと関連するオブジェクト</param>
        /// <param name="boundWidth">スケールの見た目サイズ</param>
        private void SettingScale(soLytElement objElement, out double boundWidth)
        {
            soLytMapScale objScale = null;
            soTextStyle objTextStyle = null;
            soRect objRect = null;

            objScale = objElement as soLytMapScale;
            objScale.Connect(objLytMap);

            objScale.ScaleType = 5;
            objScale.SegmentLength = 1000;
            objScale.Units = seUnits.scuKilometer;
            objScale.SegmentCount = 2;

            objTextStyle = objScale.Font;
            //objTextStyle.FontName = "ＭＳ Ｐゴシック";
            objTextStyle.FixedSize = true;
            objTextStyle.FixedTextSize = 16;
            //objTextStyle.FontHeight = 200;
            //objTextStyle.FontWidth = 400;
            //objScale.Font = objTextStyle;
            objRect = objLytMap.Bounds;
            objRect.Right = objRect.Right / 3;
            objRect.Top = objRect.Height() / 1.05;
            objScale.SetPosition(objRect);
            boundWidth = objRect.Width();
            //objScale.Editable = true;
            //objScale.Move(0, Convert.ToInt32(objRect.Height()));

            Marshal.ReleaseComObject(objRect);
            objRect = null;
            Marshal.ReleaseComObject(objTextStyle);
            objTextStyle = null;
            Marshal.ReleaseComObject(objScale);
            objScale = null;
            Marshal.ReleaseComObject(objElement);
            objElement = null;
        }

        /// <summary>
        /// ロゴ画像を設定
        /// </summary>
        /// <param name="objElement">画像と関連するオブジェクト</param>
        /// <param name="boundWidth">画像の見た目サイズ</param>
        private void SettingLog(soLytElement objElement, double boundWidth)
        {
            soLytPicture objPicture = null;
            soRect objRect = null;

            objRect = objLytMap.Bounds;
            objRect.Left = objRect.Left + boundWidth;
            objRect.Right = objRect.Right / 2;
            objRect.Top = objRect.Height() / 1.05;

            objPicture = objElement as soLytPicture;
            objPicture.Path = Utility.s_AppPath + "\\" + Utility.LOG_FILE_NAME;
            objPicture.SetPosition(objRect);
            Console.WriteLine("ロゴファイル\t---" + objPicture.Path);

            Marshal.ReleaseComObject(objRect);
            objRect = null;
            Marshal.ReleaseComObject(objPicture);
            objPicture = null;
            Marshal.ReleaseComObject(objElement);
            objElement = null;
        }

        #region IWorkspace メンバ

        public void Initialize()
        {
            routeNames = new string[] {
                "東海道本線", "東海道貨物線（品鶴含む）", "東海道貨物支線", "横須賀線", "伊東線", 
                "鶴見線（支線含む）", "南武線", "南武支線・尻手短絡線", "横浜線　", "相模線", 
                "青梅線", "五日市線", "八高線", "中央急行線", "中央総武緩行線", "総武快速・総武本線", 
                "京葉線", "成田線（空港）", "成田線（松岸）", "成田線（我孫子）", "外房線", "内房線", 
                "鹿島線", "東金線", "久留里線", "常磐線・常磐緩行線", "常磐貨物線", "東北本線", 
                "東北（回送）線", "東北貨物線", "高崎線", "武蔵野線・京葉高谷支線・京葉二俣支線", 
                "国立支線", "大宮支線", "西浦和支線", "北小金支線", "馬橋支線", "埼京線", "川越線", 
                "京浜東北・根岸線", "山手電車線", "山手貨物線", "大崎支線", "信越本線", "両毛線", 
                "上越線", "吾妻線", "日光線", "烏山線", "水戸線"};
           
            //objLayouts = superWksp.Layouts;
            objLayout.Connect(superWksp.CtlHandle);

            this.strMapName = BufferLayer.strMapName;
        }

        public void SaveToWksp()
        {
            MakeLayout();

            string strRouteNamePrefix = Utility.s_WkspName.TrimEnd('.', 's', 'm', 'w') + "　";
            int i = 0;
            foreach (string routeName in routeNames)
            {
                if (i++ < 40 && objLayout.SaveLayoutAs(strRouteNamePrefix + routeName, true))
                {
                    Console.WriteLine((i).ToString() + "\t---線路「" + routeName
                        + "」をレイアウトとしてワークスペースに保存しました。");
                    break;
                }
            }
        }

        public void OutputAsFile()
        {
            objLayout.PrintLayout(true);
        }

        public void ReleaseMemory()
        {
            Marshal.ReleaseComObject(objLytMap);
            objLytMap = null;
            
            objLayout.Disconnect();

            //Marshal.ReleaseComObject(objLayout); //COMではない？
            objLayout = null;
            //Marshal.ReleaseComObject(objLayouts);
            //objLayouts = null;
        }

        #endregion
    }
}
